<?php

namespace App;

use Swoole\Http\Server;

/**
 * Class Syncer
 * @property Server $server
 * @property \App\sender\Sender $sender
 */
class Syncer
{

    public $server;
    public $config;
    public $sender;

    public function __construct(array $config)
    {
        $this->config = $config;
        $this->loadHttp();
        $this->loadSender();
        if (!is_dir($this->config['logPath'])) {
            die('!! logPath: ' . $this->config['logPath'] . " is not existed! \n");
        }
    }

    protected function loadSender()
    {
        echo '# 载入通知 服务...' . PHP_EOL;
        if (!empty($this->config['sender'])) {
            $class = $this->config['sender']['class'];
            $params = $this->config['sender']['params'];
            $this->sender = new $class(...array_values($params));
        }
    }

    protected function loadHttp()
    {
        echo '# 载入Http 服务...' . PHP_EOL;
        $this->server = new Server($this->config['server']['host'], $this->config['server']['port']);
        $this->addHandle();
    }

    protected function addHandle()
    {
        $that = $this;
        echo '# 载入Http 响应事件...' . PHP_EOL;
        $this->server->on('Request', function ($request, $response) use ($that) {
            $requestUri = $request->server['request_uri'] . '?' . $request->server['query_string'];
            echo '@ 接受请求: ' . $requestUri . PHP_EOL;
            $config = $that->config;
            if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
                $response->end();
                return;
            }
            $response->header('Content-Type', 'text/html; charset=utf-8');
            $params = json_decode($request->rawContent(), true);
            $token = $params['password'];
            if ($token !== $config['accessSecret']) {
                $response->status('403');
                $response->end('Permission denied.');
                return;
            }
            $project = $request->get['project'];
            $projectFolder = $config['projectBase'] . $project;
            if (!is_dir($projectFolder)) {
                $response->status('500');
                $response->end('Project does not exist.');
                return;
            }
            //输出执行结果 包括错误信息，在 webhook中 可以查看和测试
            $branchData = shell_exec("cd {$projectFolder} && git branch 2>&1");
            $branch = $that->parseBranch($branchData);
            $result = shell_exec("cd {$projectFolder} && git pull 2>&1");
            // 拼装日志
            $logContent = print_r(date('Y-m-d H:i:s') . "\n\n" . $result . "\n\n", true);
            // 打印日志
            $that->printLog($project, $logContent);
            // 检查是否有消息推送配置
            if ($this->sender) {
                $noticeBody = [
                    "msgtype" => "markdown",
                    "markdown" => [
                        "title" => "代码自动下拉结果通知",
                        "text" => "【{$project}】代码自动下拉结果: \n\n" . "> 当前分支：{$branch}\n\n" . $result
                    ]
                ];
                $this->sender->sendNotice($noticeBody);
            }
            $response->end($result);
            echo '^^ 本次请求处理完成' . PHP_EOL . PHP_EOL;
        });
        echo '^^ 载入Http 响应事件 Okay' . PHP_EOL;
    }

    public function run()
    {
        echo "HttpServer start : " . $this->server->host . ":" . $this->server->port . PHP_EOL . PHP_EOL;
        $this->server->start();
    }

    protected function parseBranch(string $branchStr)
    {
        $branches = explode("\n", $branchStr);
        foreach ($branches as $branch) {
            if (strpos($branch, '*') !== false) {
                return str_replace(['*', ' '], '', $branch);
            }
        }
        return '';
    }

    protected function printLog(string $project, string $content)
    {
        $logFile = $this->config['logPath'] . $project . ".log";
        @file_put_contents($logFile, $content, FILE_APPEND);
    }

}